﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WSPay.Common.Data;

namespace WSPay.Application
{
    public interface IBaseService<T>  where T:IEntity
    {
        IQueryable<T> ReadQuery();
        IQueryable<T> Query();

        T GetByID(int id);

        IEnumerable<T> QuerySql(string sql, params object[] parameters);
    }

    public abstract class BaseService<T> : BaseService, IBaseService<T> where T:IEntity
    {
        public BaseService(IUnitOfWork unitOfWork) : base(unitOfWork)
        {
        }

        public  T GetByID(int id)
        {
            return base.GetByID<T>(id);
        }

        public  IQueryable<T> Query()
        {
            return base.Query<T>();
        }

        public  IEnumerable<T> QuerySql(string sql, params object[] parameters)
        {
            return base.QuerySql<T>(sql, parameters);
        }

        public IQueryable<T> ReadQuery()
        {
            return base.ReadQuery<T>();
        }
    }
    public abstract class BaseService
    {
        protected readonly IUnitOfWork _unitOfWork;

        protected BaseService(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        /// <summary>
        /// 只读不带跟踪的查询，一方面提高效率，二方面去除缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IQueryable<T> ReadQuery<T>() where T : IEntity
        {
            return _unitOfWork.D<T>().ReadQuery();
        }

        /// <summary>
        /// 带跟踪的实体集合查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IQueryable<T> Query<T>() where T : IEntity
        {
            return _unitOfWork.D<T>().Query();
        }

        /// <summary>
        /// 通过实体ID获得实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <returns></returns>
        public T GetByID<T>(int id) where T : IEntity
        {
            return _unitOfWork.D<T>().GetById(id);
        }

        /// <summary>
        /// 执行指定的SQL语句获得集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type"></param>
        /// <param name="sql"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public IEnumerable<T> ExecuteSql<T>(Type type, string sql, params object[] parameters) where T : class
        {
            return _unitOfWork.QuerySql<T>(sql, parameters);
        }

        /// <summary>
        /// 执行指定的SQL语句获得集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public IEnumerable<T> QuerySql<T>(string sql, params object[] parameters) where T : IEntity
        {
            return _unitOfWork.QuerySql<T>(typeof(T), sql, parameters) as IEnumerable<T>;
        }

        /// <summary>
        /// 执行制定的SQL语句进行分页处理
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="orderSql"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public IEnumerable<T> QuerySqlPage<T>(string sql, string orderSql, int pageIndex = 1, int pageSize = 20, params object[] parameters) where T : IEntity
        {
            if (string.IsNullOrEmpty(orderSql)) orderSql = "order by ID desc";
            sql = @"select * from (
               select row_number()over(" + orderSql + @")num,*
               from (" + sql + @")t)tt where num>" + (pageIndex - 1) * pageSize;
            return _unitOfWork.QuerySql<T>(typeof(T), sql, parameters) as IEnumerable<T>;
        }
    }
}
